/**
 * @file NewtonSolver.h
 * @brief 
 * @author htli (3180102114@zju.edu.cn)
 * @version 1.0
 * @date 2021-10-03
 * 
 * @copyright Copyright (c) 2021  linhuo2020
 * 
 */
#ifndef _PRO1_NEWTONSOLVER_
#define _PRO1_NEWTONSOLVER_
#include "EquationSolver.h"

class NewtonSolver : public EquationSolver
{
protected:
    const std::string Name = "Newton's Method";

public:
    using EquationSolver::EquationSolver;
    const double solve()
    {
        int k = 0;
        double u = 1;
        double x = init[0];
        for (k = 0; (k <= max_iteration); k++)
        {
            u = (*pf)(x);
            if (fabs(u) < tolerance)
            {
                break;
            };
            x -= u / ((*pdf)(x));
        };
        if (k <= max_iteration)
        {
            std::cout << "By " << Name.c_str() << ", the solution is " << x << ", in " << k << " steps, with tolerance of " << tolerance << "." << std::endl;
        }
        else
        {
            std::cout << "Warning: The given tolerance " << tolerance << " cannot be reached in " << max_iteration << " steps" << std::endl;
            std::cout << "The ouput is " << x << ", with f(x) =  " << fabs((*pf)(x)) << "." << std::endl;
        };
        return x;
    };
};

#else
//DO NOTHING
#endif